<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" href="../style/journal.css" type="text/css" />
<style type="text/css"><!--
.googleadsense {
	margin: 2px;
	padding: 0px;
//--></style><script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-65008-1";
urchinTracker();
</script><title>$Class[0] = 'Class::Accessor';</title>
</head>
<body>
<a href="index.html">Journal</a>(2005) | <a href="../blog/"><b>Blog</b></a>(2006) | <a href="http://www.fayland.org/cgi-bin/random_link.pl">RandomLink</a> | <a href="AboutFayland.html">WhoAmI</a> | <a href="LiveBookmark.html">LiveBookmark</a> | <a href="http://www.fayland.org/">HomePage</a>
<p><&lt;Previous: <a href="HTML_FillInForm.html">使用 HTML::FillInForm 的一个例子</a>&nbsp;&nbsp;>>Next: <a href="ShareURL0504.html">Share the URLs with u (Apr. 2005)</a></p>
<h1>$Class[0] = 'Class::Accessor';</h1>
<div class='content'>
<p>Category: <a href='Modules.html'>Modules</a> &nbsp; Keywords: <b>Class::Accessor</b></p><h2>prattle</h2>
闲着不知道做什么好，就去看模块源码。顺便写些翻译和代码。<br>
打算是打算写一个系列，就是不知道我的热情能持续多久了。<br>
诸位若闲着无聊，看看无妨。<br>
今天介绍下 <a href='http://search.cpan.org/perldoc?Class::Accessor'>Class::Accessor</a> 和 <a href='http://search.cpan.org/perldoc?Class::Accessor::Fast'>Class::Accessor::Fast</a>

<h2>例子</h2>
Class::Accessor - Automated accessor generation/自动化存取器<br>
假设我们写一个 People 模块。每个人都有各自属性，比如 age, gender, birthday, occupation, location, salary etc.<br>
经常要用的是获得他们的属性和设置新的属性。<br>
对应的代码为：
<pre><code>
sub occupation {
    my $self = shift;

    if(@_ == 1) {
        $self->{occupation} = shift;
    } elsif (@_ > 1) {
        $self->{occupation} = [@_];
    }
    return $self->{occupation};
}
sub age {
    my $self = shift;

    if(@_ == 1) {
        $self->{age} = shift;
    }
    return $self->{occupation};
}
</code></pre>
这样我们能用my $occupation = $marry->occupation;来获取marry的职业，而用$marry->occupation('doctor', 'teacher');（假设她早上当医生下午当老师）来设置它的职业。<br>
而 gender等其他的属性也要重复这段代码，这样写下来的话代码太冗长而且不符合我们的美德懒惰了。<br>
当然我们有进一步的写法，写一个通用的 set, get 函数：
<pre><code>
sub set {
    my($self, $key) = splice(@_, 0, 2);

    if(@_ == 1) {
        $self->{$key} = $_[0];
    }
    elsif(@_ > 1) {
        $self->{$key} = [@_];
    }
    else {
        require Carp;
        &Carp::confess("Wrong number of arguments received");
    }
}
sub get {
    my $self = shift;

    if(@_ == 1) {
        return $self->{$_[0]};
    }
    elsif( @_ > 1 ) {
        return @{$self}{@_};
    }
    else {
        require Carp;
        &Carp::confess("Wrong number of arguments received.");
    }
}
</code></pre>
这样我们能用 $marry->get('age') 来获取她的年龄，用 $marry->set('age', '33'); 来设置它的年龄。<br>
看上去似乎很不错了，但是 marry 的 gender 是 female, 一生下来就定死了的。而我们希望她的 salary 只能写入不能被人读取。<br>
怎么做好呢？打个广告，不妨试试 Class::Accessor
<pre><code>
package People;
use base qw(Class::Accessor);

People->mk_accessors(qw(age occupation location));
People->mk_ro_accessors(qw(gender birthday));
People->mk_wo_accessors('salary');

1;

#！/usr/bin/perl
use People;

my $marry = People->new({
    'gender' => 'female',
    'birthday' => '2005-4-26',
    'age' => 1,
});

print $marry->gender;
$marry->salary('100');
$marry->age('2');
print $marry->age; # print 2
# etc ...
# as follow is wrong
# print $marry->salary; # salary is write-only
# $marry->gender('man'); # gender is read-only
</code></pre>
非常简单，就三句代码可以定义无数个函数。:)

<h2>Class::Accessor && Class::Accessor::Fast</h2>
Class::Accessor::Fast 是 Class::Accessor 的缩写版本，它舍弃了 Class::Accessor 中的 set & get （这东西的作用参见 perldoc <a href='http://search.cpan.org/perldoc?Class::Accessor'>Class::Accessor</a> ），所以速度更快。一般而言不用自己定制 set,get 的话推荐使用 Class::Accessor::Fast<br>
<a href='http://search.cpan.org/perldoc?Class::DBI'>Class::DBI</a> 用来 Class::Accessor ,而 <a href='http://search.cpan.org/perldoc?Catalyst'>Catalyst</a> 用了Class::Accessor::Fast.<p>
Enjoy!</div>
<p><&lt;Previous: <a href="HTML_FillInForm.html">使用 HTML::FillInForm 的一个例子</a>&nbsp;&nbsp;>>Next: <a href="ShareURL0504.html">Share the URLs with u (Apr. 2005)</a></p>
<p><strong>Options:</strong> <a href='http://del.icio.us/post?title=$Class%5B0%5D%20=%20'Class::Accessor';&url=http://www.fayland.org/journal/Class-Accessor.html'>+Del.icio.us</a></p>
<strong>Related items</strong>
<ul><li><a href='050328.html'>Catalyst & Eplanet</a> < <span class='digit'>2005-03-28 13:19:19</span> ></li><li><a href='050423.html'>Day [05.4.23] stay with me</a> < <span class='digit'>2005-04-23 16:17:02</span> ></li><li><a href='Catalyst_Authenticate.html'>Catalyst Authenticate</a> < <span class='digit'>2005-09-26 12:50:39</span> ></li><li><a href='Catalyst_Flaw.html'>Catalyst 的一个不足（一个已去掉）</a> < <span class='digit'>2005-09-27 13:44:31</span> ></li><li><a href='Catalyst_Session_Win32.html'>Catalyst 在 Win32 下的 Session</a> < <span class='digit'>2005-09-29 11:08:04</span> ></li><li><a href='Catalyst_NoFavIcon.html'>Catalyst && favicon.ico</a> < <span class='digit'>2005-09-30 00:57:57</span> ></li><li><a href='Catalyst_Overview.html'>我对 Catalyst 的理解和介绍</a> < <span class='digit'>2005-10-08 01:39:40</span> ></li><li><a href='Catalyst_XMLRPC.html'>Catalyst && XML-RPC</a> < <span class='digit'>2005-10-11 21:50:30</span> ></li><li><a href='Catalyst_YAML.html'>Catalyst config YAML</a> < <span class='digit'>2005-12-10 12:50:39</span> ></li><li><a href='CatalystAdventCalendar_CN.html'>Catalyst Advent Calendar 中文版</a> < <span class='digit'>2005-12-15 23:28:40</span> ></li></ul>
Created on <span class="digit">2005-04-26 15:07:30</span>, Last modified on <span class="digit">2005-04-26 15:38:28</span><br />
Copyright 2004-2005 All Rights Reserved. Powered by <a href="Eplanet.html">Eplanet</a> && <a href='http://catalyst.perl.org'>Catalyst</a> 5.62.
</body>
</html>